import modelExtend from 'dva-model-extend'
import {
  query,
  create,
  update,
  deleteRole,
  listResourceByRole,
  bindResource,
  unbindResource,
  listUserIdByRole,
  bindUser,
  unbindUser,
  listMenu,
  getMenu,
  bindMenu,
  refreshRequestMap,
  bindedResourceList,
  bindedResourceGrounp,
  unbindedResourceGrounp,
  batchUpdateResourceGroup
} from 'services/security/role'
import * as resourceService from 'services/security/resource'
import * as userService from 'services/security/user'
import { lwjPageModel } from 'utils/model'
import { Modal, message } from 'antd'

export default modelExtend(lwjPageModel, {
  namespace: 'role',
  state: {
    pageOptions: {
      sort: 'createTime',
      order: 'DESC'
    },
    queryParam: {},
    // 是否显示修改角色对Modal
    isShowUpdateModal: false,
    isUpdate: false,
    // 当前要修改对角色
    currentUpdateItem: {},
    // 选中角色列的ID
    rowClicked: '',
    // 角色拥有的权限
    roleResources: [],
    // 资源列表
    resourcesItems: [],
    // 资源列表的分页
    resourcePagination: {
      current: 1,
      total: 0,
      showTotal: total => `共 ${total} 条`,
      showSizeChanger: true,
      showQuickJumper: true,
      defaultPageSize: 10
    },
    resourceQueryParam: {},
    // 是否显示选择资源的Modal
    isShowSearchResourceModal: false,
    // 待绑定的资源
    toBeBoundResources: [],
    // 待解绑的资源
    toBeUnBoundResources: [],
    // 用户列表
    userItems: [],
    // 用户列表的分页
    userPagination: {
      current: 1,
      total: 0,
      showTotal: total => `共 ${total} 条`,
      showSizeChanger: true,
      showQuickJumper: true,
      defaultPageSize: 10
    },
    userQueryParam: {},
    // 是否显示选择用户的Modal
    isShowSearchUserModal: false,
    // 待绑定的用户
    toBeBoundUser: [],
    // 待解绑的用户
    toBeUnBoundUser: [],
    // 拥有某角色的用户
    roleUser: [],
    // 当前tab页
    defaultActiveKey: '2',
    //所有菜单
    menus: [],
    //获取所选的菜单
    selectedMenus: [],
    //绑定菜单按钮的状态
    bindMenuButtonVisible: true,
    // 资源组列表
    resourceGrounpLists: [],
    // 绑定的资源组
    boundResourceList: []
  },
  subscriptions: {
    setup({ dispatch, history }) {
      history.listen(({ pathname }) => {
        if (pathname === '/role') {
          dispatch({ type: 'query', payload: {} })
        }
      })
    }
  },
  effects: {
    * query({
      payload
    }, { select, call, put }) {
      yield put({
        type: 'asyncData',
        payload: {
          ...payload
        }
      })
      const pageOptions = yield select(({ role }) => role.pageOptions)
      let queryParam = yield select(({ role }) => role.queryParam)
      const queryPayload = {
        ...pageOptions,
        queryParam: {
          ...queryParam
        }
      }
      const data = yield call(query, queryPayload)
      // 权限列表接口和分销的列表接口返回结构不一致，需要重新组装数据
      let assembledData = {}
      assembledData.content = data.items
      assembledData.totalElements = data.totalCount
      assembledData.totalPages = data.totalPages
      assembledData.current = data.page
      assembledData.number = data.page - 1
      yield put({
        type: 'querySuccess',
        payload: {
          ...assembledData
        }
      })
    },
    /**
     * 所有权限的列表查询
     */ * queryResources({
      payload
    }, { select, call, put }) {
      yield put({
        type: 'asyncResourcesData',
        payload: {
          ...payload
        }
      })
      const pageOptions = yield select(({ role }) => role.pageOptions)
      const resourceQueryParam = yield select(({ role }) => role.resourceQueryParam)
      const queryPayload = {
        ...pageOptions,
        queryParam: {
          ...resourceQueryParam
        }
      }
      const data = yield call(resourceService.query, queryPayload)
      // 权限列表接口和分销的列表接口返回结构不一致，需要重新组装数据
      let assembledData = {}
      assembledData.content = data.items
      assembledData.totalElements = data.totalCount
      assembledData.totalPages = data.totalPages
      assembledData.current = data.page
      assembledData.number = data.page - 1
      yield put({
        type: 'queryResourcesSuccess',
        payload: {
          ...assembledData
        }
      })
    },
    /**
     * 所有用户的列表接口
     */ * queryUser({
      payload
    }, { select, call, put }) {
      yield put({
        type: 'asyncUserData',
        payload: {
          ...payload
        }
      })
      const pageOptions = yield select(({ role }) => role.pageOptions)
      const userQueryParam = yield select(({ role }) => role.userQueryParam)
      userQueryParam.isEnabled = true
      const queryPayload = {
        ...pageOptions,
        queryParam: {
          ...userQueryParam
        }
      }
      const data = yield call(userService.query, queryPayload)
      yield put({
        type: 'queryUserSuccess',
        payload: {
          ...data
        }
      })
    },
    /**
     * 创建角色
     */ * createRole({
      payload
    }, { select, call, put }) {
      const items = yield select(({ role }) => role.items)
      if(_.isArray(items)){
        const admin = items.filter((item) => {
          return item.name==="ROLE_ADMIN"
        })
        if(admin.length  === 1){
          payload.roleData.hierarchyId = admin[0].id
        }
      }
      yield call(create, payload.roleData)
      yield call(refreshRequestMap)
      yield put({ type: 'hideUpdateRoleModal', payload: {} })
      yield put({ type: 'query', payload: {} })
    },
    /**
     * 修改角色
     */ * updateRole({
      payload
    }, { select, call, put }) {
      const items = yield select(({ role }) => role.items)
      if(_.isArray(items)){
        const admin = items.filter((item) => {
          return item.name==="ROLE_ADMIN"
        })
        if(admin.length  === 1){
          payload.roleData.hierarchyId = admin[0].id
        }
      }
      yield call(update, payload.roleData)
      yield call(refreshRequestMap)
      yield put({ type: 'hideUpdateRoleModal', payload: {} })
      yield put({ type: 'query', payload: {} })
    },
    /**
     * 删除角色
     */ * deleteRole({
      payload
    }, { select, call, put }) {
      yield call(deleteRole, payload.roleId, payload.roleVersion)
      yield call(refreshRequestMap)
      yield put({ type: 'query', payload: {} })
    },
    /**
     * 查询角色包含的权限
     */ * listResourceByRole({
      payload
    }, { select, call, put }) {
      const data = yield call(listResourceByRole, payload.roleId)
      yield put({
        type: 'updateRoleResources',
        payload: {
          roleResources: data.list
        }
      })
    },
    /**
     * 资源组相关
     */ * userGroupList({
      payload
    }, { select, call, put }) {
      const data = yield call(bindedResourceList, payload)

      yield put({
        type: 'updateResourceGrounpList',
        payload: {
          resourceGrounpLists: data.result
        }
      })
    },

    * storeResourcesGroup({
      payload
    }, { select, call, put }) {
      const { boundResourceList, roleId } = payload
      let success = true
      let res = {}
      let bindIds = boundResourceList.map(item => item.id)
      res = yield call(batchUpdateResourceGroup, { params: bindIds, roleId })
      if (res.success !== true) {
        success = false
      }

      yield put({
        type: 'userGroupList',
        payload: { roleId }
      })

      if (success) {
        message.success('绑定成功')
      } else {
        message.error(res.message)
      }
    },

    * refreshResourceGroup({
      payload
    }, { select, call, put }) {
      const res = yield call(refreshRequestMap)
      if (res.success) {
        message.success('刷新成功')
      } else {
        message.error(res.message)
      }
    },

    /**
     *查询拥有该角色的用户
     */ * listUserByRole({
      payload
    }, { select, call, put }) {
      const userIds = yield call(listUserIdByRole, payload.roleId)
      let data = []
      if (userIds.result && userIds.result.length > 0) {
        data = yield call(userService.listByUserIds, userIds.result)
      }
      yield put({
        type: 'updateRoleUser',
        payload: {
          roleUser: data.result
        }
      })
    },
    /**
     *  绑定资源
     */ * bindResource({
      payload
    }, { select, call, put }) {
      yield call(bindResource, payload.rowClicked, payload.toBeBoundResources)
      yield call(refreshRequestMap)
      yield put({ type: 'hideSearchResourceModal', payload: {} })
      yield put({
        type: 'listResourceByRole',
        payload: {
          roleId: payload.rowClicked
        }
      })

    },
    /**
     * 解绑资源
     */ * unbindResource({
      payload
    }, { select, call, put }) {
      yield call(unbindResource, payload.rowClicked, payload.toBeUnBoundResources)
      yield call(refreshRequestMap)
      yield put({
        type: 'updateToBeUnBoundResources',
        payload: {
          toBeBoundResources: []
        }
      })
      yield put({
        type: 'listResourceByRole',
        payload: {
          roleId: payload.rowClicked
        }
      })
    },
    /**
     *  绑定用户
     */ * bindUser({
      payload
    }, { select, call, put }) {
      yield call(bindUser, payload.rowClicked, payload.toBeBoundUser)
      yield call(refreshRequestMap)
      yield put({ type: 'hideSearchUserModal', payload: {} })
      yield put({
        type: 'listUserByRole',
        payload: {
          roleId: payload.rowClicked
        }
      })
    },
    /**
     * 解绑用户
     */ * unbindUser({
      payload
    }, { select, call, put }) {
      yield call(unbindUser, payload.rowClicked, payload.toBeUnBoundUser)
      yield call(refreshRequestMap)
      yield put({
        type: 'updateToBeUnBoundUser',
        payload: {
          toBeBoundResources: []
        }
      })
      yield put({
        type: 'listUserByRole',
        payload: {
          roleId: payload.rowClicked
        }
      })
    },
    * listMenu({
      payload
    }, { select, call, put }) {
      const data = yield call(listMenu)
      yield put({
        type: 'menuSuccess',
        payload: {
          menus: data
        }
      })
    },
    * getRoleMenu({
      payload
    }, { select, call, put }) {
      const data = yield call(getMenu, payload.roleId)
      yield put({
        type: 'menuSuccess',
        payload: {
          menus: data
        }
      })
    },
    * bindMenu({
      payload
    }, { select, call, put }) {
      const data = yield call(bindMenu, payload)
      if (data.code === 0) {
        Modal.success({ title: '绑定成功', content: '更新菜单绑定成功' })
      }
      yield put({
        type: 'showBindMenuButton',
        payload: {
          visible: true
        }
      })
    },
    * frontSearch({
      payload
    }, { select, call, put }) {
      if (payload.searchType === 'resource') {
        const data = yield call(listResourceByRole, payload.roleId)
        yield put({
          type: 'updateRoleResources',
          payload: {
            roleResources: data.list
          }
        })
        let roleResources = yield select(({ role }) => role.roleResources)
        if (!_.isEmpty(payload) && !_.isEmpty(payload.searchText)) {
          roleResources = _.filter(roleResources, (item) => {
            return item
              .name
              .indexOf(payload.searchText) > -1 || item
                .url
                .indexOf(payload.searchText) > -1
          })
          yield put({
            type: 'frontFilterSuccess',
            payload: {
              roleResources: roleResources
            }
          })
        } else {
          const data = yield call(listResourceByRole, payload.roleId)
          yield put({
            type: 'updateRoleResources',
            payload: {
              roleResources: data.list
            }
          })
        }
      } else {
        const userIds = yield call(listUserIdByRole, payload.roleId)
        if (userIds.result && userIds.result.length > 0) {
          const data = yield call(userService.listByUserIds, userIds.result)
          yield put({
            type: 'updateRoleUser',
            payload: {
              roleUser: data.result
            }
          })
          let roleUser = yield select(({ role }) => role.roleUser)
          if (!_.isEmpty(payload) && !_.isEmpty(payload.searchText)) {
            roleUser = _.filter(roleUser, (item) => {
              const checkItem = (item) => {
                const matchDisplayName = item.displayName === null ? false : item.displayName.indexOf(payload.searchText) > -1
                const matchMobile = item.mobile === null ? false : item.mobile.indexOf(payload.searchText) > -1
                const matchEmail = item.email === null ? false : item.email.indexOf(payload.searchText) > -1
                return matchDisplayName || matchMobile || matchEmail
              }
              // return item
              //   .displayName
              //   .indexOf(payload.searchText) > -1 || item
              //     .mobile
              //     .indexOf(payload.searchText) > -1 || item
              //       .email
              //       .indexOf(payload.searchText) > -1
              return checkItem(item)
            })
            yield put({
              type: 'frontFilterSuccess',
              payload: {
                roleUser: roleUser
              }
            })
          }
        }
      }
    }
  },
  reducers: {
    frontFilterSuccess(state, { payload }) {
      return {
        ...state,
        ...payload,
        roleResources: payload.roleResources,
        roleUser: payload.roleUser
      }
    },
    onSelectChange(state, { payload }) {
      return {
        ...state,
        ...payload
      }
    },
    showUpdateRoleModal(state, { payload }) {
      return {
        ...state,
        ...payload,
        isShowUpdateModal: true
      }
    },
    hideUpdateRoleModal(state, { payload }) {
      return {
        ...state,
        ...payload,
        isShowUpdateModal: false,
        currentUpdateItem: {}
      }
    },
    toUpdateRole(state, { payload }) {
      return {
        ...state,
        ...payload,
        currentUpdateItem: payload.currentRole,
        isUpdate: true
      }
    },
    updateRowClicked(state, { payload }) {
      return {
        ...state,
        ...payload,
        rowClicked: payload.rowClicked
      }
    },
    updateRoleResources(state, { payload }) {
      return {
        ...state,
        ...payload,
        roleResources: payload.roleResources
      }
    },
    updateRoleUser(state, { payload }) {
      return {
        ...state,
        ...payload,
        roleUser: payload.roleUser
      }
    },
    asyncResourcesData(state, { payload }) {
      if (payload.isTablePagination) {
        delete payload.isTablePagination
        return {
          ...state,
          resourceQueryParam: {
            ...state.resourceQueryParam,
            ...payload
          }
        }
      } else {
        return {
          ...state,
          resourceQueryParam: {
            ...payload
          }
        }
      }
    },
    queryResourcesSuccess(state, { payload }) {
      return {
        ...state,
        resourcesItems: payload.content,
        resourcePagination: {
          ...state.resourcePagination,
          current: payload.number + 1,
          total: payload.totalElements
        }
      }
    },
    showSearchResourceModal(state, { payload }) {
      return {
        ...state,
        ...payload,
        isShowSearchResourceModal: true
      }
    },
    hideSearchResourceModal(state, { payload }) {
      return {
        ...state,
        ...payload,
        isShowSearchResourceModal: false,
        toBeBoundResources: []
      }
    },
    updateToBeBoundResources(state, { payload }) {
      return {
        ...state,
        ...payload,
        toBeBoundResources: payload.toBeBoundResources
      }
    },
    updateToBeUnBoundResources(state, { payload }) {
      return {
        ...state,
        ...payload,
        toBeUnBoundResources: payload.toBeUnBoundResources
      }
    },
    updateToBeUnBoundUser(state, { payload }) {
      return {
        ...state,
        ...payload,
        toBeUnBoundUser: payload.toBeUnBoundUser
      }
    },
    emptyResources(state, { payload }) {
      return {
        ...state,
        ...payload,
        roleResources: [],
        rowClicked: ''
      }
    },
    asyncUserData(state, { payload }) {
      if (payload.isTablePagination) {
        delete payload.isTablePagination
        return {
          ...state,
          userQueryParam: {
            ...state.userQueryParam,
            ...payload
          }
        }
      } else {
        return {
          ...state,
          userQueryParam: {
            ...payload
          }
        }
      }
    },
    queryUserSuccess(state, { payload }) {
      return {
        ...state,
        userItems: payload.content,
        userPagination: {
          ...state.resourcePagination,
          current: payload.number + 1,
          total: payload.totalElements
        }
      }
    },
    showSearchUserModal(state, { payload }) {
      return {
        ...state,
        ...payload,
        isShowSearchUserModal: true
      }
    },
    hideSearchUserModal(state, { payload }) {
      return {
        ...state,
        ...payload,
        isShowSearchUserModal: false,
        toBeBoundUser: []
      }
    },
    updateToBeBoundUser(state, { payload }) {
      return {
        ...state,
        ...payload,
        toBeBoundUser: payload.toBeBoundUser
      }
    },
    emptyRoleParams(state, { payload }) {
      return {
        ...state,
        ...payload,
        rowClicked: '',
        queryParam: {}
      }
    },
    updateDefaultActiveKey(state, { payload }) {
      return {
        ...state,
        ...payload,
        defaultActiveKey: payload.defaultActiveKey
      }
    },
    emptyMenu(state, { payload }) {
      return {
        ...state,
        ...payload,
        menus: []
      }
    },
    getSelectedMenus(state, { payload }) {
      return {
        ...state,
        ...payload,
        selectedMenus: payload.selectedMenus
      }
    },
    menuSuccess(state, { payload }) {
      const menuList = payload.menus.list
      menuList.forEach(element => {
        element.parentId = element.mpid
        delete element.mpid
      })
      return {
        ...state,
        ...payload,
        menus: menuList
      }
    },
    showBindMenuButton(state, { payload }) {
      return {
        ...state,
        ...payload,
        bindMenuButtonVisible: payload.visible
      }
    },
    /**
     * 资源组列表
     */
    updateResourceGrounpList(state, { payload }) {
      const { resourceGrounpLists } = payload
      resourceGrounpLists.sort((a, b) => {
        let nameA = a.code.toUpperCase() // ignore upper and lowercase
        let nameB = b.code.toUpperCase() // ignore upper and lowercase
        if (nameA < nameB) {
          return -1
        }
        if (nameA > nameB) {
          return 1
        }

        return 0
      })

      state.resourceGrounpLists = resourceGrounpLists

      return {
        ...state,
      }
    },
    bindResourceList(state, { payload }) {
      state.boundResourceList = payload

      return {
        ...state,
      }
    },
    emptyresourceList(state, { payload }) {
      state.resourceGrounpLists = []
      return {
        ...state
      }
    }
  }
})
